/*
 * @Author: Jiraiya
 * @Date: 2020-05-12 15:40:39
 * @LastEditors: Jiraiya
 * @LastEditTime: 2020-05-12 15:47:31
 * @Description: 
 */
export function createElement(type, config, children) {
    let propName;
  
    // Reserved names are extracted
    const props = {};
  
    let key = null;
    let ref = null;
    let self = null;
    let source = null;
    
    
    // 收集props和属性 自带四个属性ref/key/_self/_source
    if (config != null) { 
      if (hasValidRef(config)) {
        ref = config.ref;
      }
      if (hasValidKey(config)) {
        key = '' + config.key;
      }
  
      self = config.__self === undefined ? null : config.__self;
      source = config.__source === undefined ? null : config.__source;
      // Remaining properties are added to a new props object
      for (propName in config) {
        if (
          hasOwnProperty.call(config, propName) &&
          !RESERVED_PROPS.hasOwnProperty(propName)
        ) {
          props[propName] = config[propName];
        }
      }
    }
  
    // 子节点收集
    const childrenLength = arguments.length - 2;
    if (childrenLength === 1) { //单个子节点 则返回对象
      props.children = children;
    } else if (childrenLength > 1) { //多个子节点，则放在数组
      const childArray = Array(childrenLength);
      for (let i = 0; i < childrenLength; i++) {
        childArray[i] = arguments[i + 2];
      }
      props.children = childArray;
    }
  
    // 对于props不存在的值，采用默认值赋值
    // class Test{}  Test.defaultProps = {}
    if (type && type.defaultProps) {
      const defaultProps = type.defaultProps;
      for (propName in defaultProps) {
        if (props[propName] === undefined) {
          props[propName] = defaultProps[propName];
        }
      }
    }
    return ReactElement(
      type,
      key,
      ref,
      self,
      source,
      ReactCurrentOwner.current,
      props,
    );
}



const ReactElement = function(type, key, ref, self, source, owner, props) {
    const element = {
      // This tag allows us to uniquely identify this as a React Element
      $$typeof: REACT_ELEMENT_TYPE,
  
      type: type,
      key: key,
      ref: ref,
      props: props,
  
      // 记录负责创建此元素的组件
      _owner: owner,
    };
    
    return element;
};